package com.org.gundutubruk;

import java.util.ArrayList;
import com.org.gundutubruk.Connection;
import com.org.gundutubruk.Connection.OnConnectionLostListener;
import com.org.gundutubruk.Connection.OnConnectionServiceReadyListener;
import com.org.gundutubruk.Connection.OnIncomingConnectionListener;
import com.org.gundutubruk.Connection.OnMaxConnectionsReachedListener;
import com.org.gundutubruk.Connection.OnMessageReceivedListener;
import com.org.gundutubruk.ServerListActivity;
import android.app.Activity;
import android.app.ListActivity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.WindowManager;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.Toast;

public class RoomMultiPlayer extends ListActivity {
	public static final String TAG = "RoomMultiPlayer";
	
	public int mType;//0 untuk server 1 untuk client
	private Connection mConnection;
    private static final int SERVER_LIST_RESULT_CODE = 42;
    private static final int GAME_RESULT_CODE = 99;
    private RoomMultiPlayer self;    
    private ArrayAdapter<String> mArrayAdapter;//nampung list yang mau ditampilin (berisi nama player dan jumlah gundu)        
    private ArrayList<PlayerDevice> mArrPlayerDevice;//nampung data player per device yang terhubung
    
    private Button btnMulai;
    
    //data player yang dipilih di device
    private String namaPlayer;
    private int jumGundu;    
    private int avatar;	   
    
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);		
		self = this;
		Intent startingIntent = getIntent();
		mType = startingIntent.getIntExtra("TYPE", 0);
		mConnection = new Connection(this, serviceReadyListener);		
					
		getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
		
		mArrayAdapter = new ArrayAdapter<String>(this, R.layout.list_item);
		mArrPlayerDevice = new ArrayList<PlayerDevice>();				
		
		setListAdapter(mArrayAdapter);		
		
		setContentView(R.layout.room_multiplayer);
		
		namaPlayer = startingIntent.getStringExtra("namaPlayer");
		jumGundu = startingIntent.getIntExtra("jumGundu", 0);
		avatar = startingIntent.getIntExtra("avatar", 0);
		
		btnMulai = (Button) findViewById(R.id.btnMulai);
		btnMulai.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View arg0) {
				mulaiGame();
			}
		});
		if(mType==1) {//jika client			
			btnMulai.setVisibility(View.INVISIBLE);			
		}
	}
	
	private OnMessageReceivedListener dataReceivedListener = new OnMessageReceivedListener() {
        public void OnMessageReceived(String device, String message) {            	        	
        	Log.d(TAG,"Pesan Datang:" + message);
        	if(mType==1 && message.startsWith("REQUEST:")) {//berarti device tersebut meminta data player yang dipilih client        		
        		Log.d(TAG,"MESSAGE RECEIVED : " + message);
        		//tambah data player server di client
        		String[] data = message.substring(8).split("::::::::");
        		addPlayer(device, data[0], Integer.parseInt(data[1]),Integer.parseInt(data[2]));
        		//kirim data player client ke server
        		mConnection.sendMessage(device, "RESPOND_TO_REQUEST:" + namaPlayer + "::::::::" + jumGundu+"::::::::"+avatar);        
        		Log.d("TAG","MESSAGE SENT : RESPOND_TO_REQUEST:" + namaPlayer + "::::::::" + jumGundu);
        	}else if(mType==0 && message.startsWith("RESPOND_TO_REQUEST:")) {//server menerima data player client
        		Log.d(TAG,"MESSAGE RECEIVED BY SERVER : RESPOND_TO_REQUEST");
        		//simpan data player
        		String[] data = message.substring(19).split("::::::::");        		
        		addPlayer(device, data[0], Integer.parseInt(data[1]),Integer.parseInt(data[2]));        		       		        		 
        		StringBuilder sb = new StringBuilder("ADD_PLAYER:");
        		for(PlayerDevice aPlayerDevice:mArrPlayerDevice) {//untuk semua player yang tercatat di server
        			sb.append(aPlayerDevice.namaPlayer).append("::::::::").append(aPlayerDevice.jumGundu).append("::::::::").append(aPlayerDevice.avatar).append("::::::::").append(aPlayerDevice.device).append("::::::::");           			
        		}
        		//broadcast ke semua client, semua data player yang tercatat di server  
        		mConnection.broadcastMessage(sb.toString());
        		Log.d(TAG,"MESSAGE BROADCAST : " + sb.toString());
        	}else if(mType==1 && message.startsWith("ADD_PLAYER:")) {//jika client menerima data player
        		//simpan data player
        		Log.d(TAG,"MESSAGE RECEIVED BY CLIENT : ADD_PLAYER");
        		String[] data = message.substring(11).split("::::::::");        		
        		for(int i=0;i<data.length;i+=4) {        			
        			addPlayer(data[i+3],data[i],Integer.parseInt(data[i+1]),Integer.parseInt(data[i+2]));
        		}
        	}else if(message.startsWith("UPDATE_PLAYER:")) {
        		String[] data = message.substring(14).split("::::::::");        
        		//update player di device tersebut
        		Utility.playerHolder.updatePlayerData(self, data[0], Integer.parseInt(data[1]), Integer.parseInt(data[2]), Boolean.parseBoolean(data[3]));
        	}else{
        		//FIXME:workaround
        		//beri tau client untuk mengirimkan data player yang dipakai
                mConnection.sendMessage(device, "REQUEST:" + namaPlayer + "::::::::" + jumGundu+ "::::::::" + avatar);                      		
                Log.d("TAG","MESSAGE SENT : REQUEST");
        	}
        }
    };
    
    private OnMaxConnectionsReachedListener maxConnectionsListener = new OnMaxConnectionsReachedListener() {
        public void OnMaxConnectionsReached() {
            Log.e(TAG, "Max connections reached!");
        }
    };
    
    //dipanggil di server jika ada client berhasil connect
    private OnIncomingConnectionListener connectedListener = new OnIncomingConnectionListener() {
        public void OnIncomingConnection(String device) {                	        
        	Log.d(TAG,"CONNECTEDLISTENER");
        	/*
        	 * FIXME : perilaku aneh entah kenapa eksekusi dibawah ini dilewati, server setelah CONNECTEDLISTENER
        	 * 		   malah menerima pesan dengan nama bluetooth client.Coba liat workaround di dataReceivedListener
        	 */        	                      
        }
    };

    private OnConnectionLostListener disconnectedListener = new OnConnectionLostListener() {
        public void OnConnectionLost(String device) {        	        	        	
        	delPlayer(device);
        	if(mType==1) {
        		//jika client, langsung keluar dari room
        		overridePendingTransition(R.anim.fade, R.anim.hold);
        		finish();
        	}
        }
    };

    private OnConnectionServiceReadyListener serviceReadyListener = new OnConnectionServiceReadyListener() {        
		public void OnConnectionServiceReady() {
		   if(mType==0) {			  
        	   mConnection.startServer(4, connectedListener, maxConnectionsListener,dataReceivedListener, disconnectedListener);
        	   //isi data si server dengan data diri sendiri
       		   addPlayer(mConnection.getAddress(),namaPlayer,jumGundu,avatar);
           }else{        	   
        	   Log.d("TAG","MULAI SERVERLISTACTIVITY");
        	   Intent serverListIntent = new Intent(self, ServerListActivity.class);        	   
               startActivityForResult(serverListIntent, SERVER_LIST_RESULT_CODE);               
           }
        }
    };
    
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    	if ((resultCode == Activity.RESULT_OK) && (requestCode == SERVER_LIST_RESULT_CODE)) {
            String device = data.getStringExtra(ServerListActivity.EXTRA_SELECTED_ADDRESS);
            int connectionStatus = mConnection.connect(device, dataReceivedListener,disconnectedListener);
            if (connectionStatus != Connection.SUCCESS) {
            	Log.d(TAG,"Gagal konek");
                Toast.makeText(this, "Unable to connect; please try again.", 1).show();
            }else if(connectionStatus == Connection.SUCCESS){
            	Log.d(TAG,"Koneksi sukses");
            	Toast.makeText(this, "Koneksi sukses!", Toast.LENGTH_SHORT).show();            	
            	mConnection.broadcastMessage(mConnection.getName());            	
            }
            return;
        }else if(requestCode==SERVER_LIST_RESULT_CODE && resultCode == Activity.RESULT_CANCELED) {
        	overridePendingTransition(R.anim.fade, R.anim.hold);
        	this.finish();        	
        }else if(requestCode==GAME_RESULT_CODE && resultCode==Activity.RESULT_OK) {        	    			
        	//persiapan buat munculin activity pemenang
        	Bundle b = new Bundle();
        	Intent intent = new Intent(self,WInnerActivity.class);
        	String namamenang = data.getStringExtra(GameActivity.EXTRA_WINNER_NAME);
        	int gunduMenang = data.getIntExtra(GameActivity.EXTRA_WINNER_GUNDU, 0);
	        b.putBoolean("isMultiplayer", true);
	        b.putString("namamenang", namamenang);
	        if(getPlayerDeviceWithPlayerName(namamenang)!=null) {
	        	b.putInt("avatarid", getPlayerDeviceWithPlayerName(namamenang).avatar);
	        }
	        b.putInt("gundumenang", gunduMenang);
	        intent.putExtras(b);        	
        	
        	//persiapan buat munculin activity list rekap        	
        	String[] arrNamaPlayer = data.getStringArrayExtra(GameActivity.EXTRA_LOSERS_NAMES);
        	int[] jumGundu = data.getIntArrayExtra(GameActivity.EXTRA_LOSERS_GUNDU);
        	Player[] arrPlayer = new Player[arrNamaPlayer.length];
        	for(int i=0;i<arrNamaPlayer.length;i++) {
        		if(getPlayerDeviceWithPlayerName(arrNamaPlayer[i])!=null) {
        			arrPlayer[i] = new Player(arrNamaPlayer[i],getPlayerDeviceWithPlayerName(arrNamaPlayer[i]).avatar,i);
        		}
        	}
        	ListRekap.paraPemain = arrPlayer;
        	ListRekap.jumGundu = jumGundu;
        	
	        //*******update semua player yang terdaftar ke hapenya masing-masing
        	
        	//update data pemenang        	
        	if(getPlayerDeviceWithPlayerName(namamenang)!=null && GameSettingHolder.modegame == GameSettingHolder.APOLLO || GameSettingHolder.modegame == GameSettingHolder.BULETAN) {			    			
        		updatePlayerOnDevice(getPlayerDeviceWithPlayerName(namamenang).device, namamenang, gunduMenang, GameSettingHolder.taruhan, true);
    		}else if(getPlayerDeviceWithPlayerName(namamenang)!=null && GameSettingHolder.modegame==GameSettingHolder.DUEL) {
    			//workaround buat duel(baca petunjuk updateplayerdata)			    			
    			updatePlayerOnDevice(getPlayerDeviceWithPlayerName(namamenang).device, namamenang, gunduMenang + 1, GameSettingHolder.taruhan, true);
    		}
        	
        	//update data yang kalah
        	for(int i=0;i<arrNamaPlayer.length;i++) {
        		if(getPlayerDeviceWithPlayerName(arrNamaPlayer[i])!=null) {
        			updatePlayerOnDevice(getPlayerDeviceWithPlayerName(arrNamaPlayer[i]).device,arrNamaPlayer[i],jumGundu[i],GameSettingHolder.taruhan,false);
        		}
        	}
        	//**********************
        	startActivity(intent);
        	overridePendingTransition(R.anim.fade, R.anim.hold);
        	finish();
        }
    }
    
    @Override
    protected void onDestroy() {
        if (mConnection != null) {
            mConnection.shutdown();
        }       
        super.onDestroy();
    }
    
    //mengembalikan true jika device sudah ada
    private boolean checkPlayerDeviceAlreadyExist(String device) {
    	for(int i=0;i<mArrPlayerDevice.size();i++) {
    		if(mArrPlayerDevice.get(i).device.equals(device)) {
    			return true;
    		}
    	}
    	return false;
    }
    
    //nambahin player device
    private void addPlayer(String device,String namaPlayer,int jumGundu, int avatar) {
    	if(!checkPlayerDeviceAlreadyExist(device)) {    		    					
    		mArrPlayerDevice.add(new PlayerDevice(device,namaPlayer, jumGundu, avatar));
    		updatePlayerList();
    	}
    }    
    
    private void delPlayer(String device) {
    	for(int i=0;i<mArrPlayerDevice.size();i++) {
    		if(mArrPlayerDevice.get(i).device.equals(device)) {//jika ada di list device
    			mArrPlayerDevice.remove(i);
    			updatePlayerList();
    			break;
    		}
    	}
    }
    
    //refresh arrayadapter
    private void updatePlayerList() {    	    	
		self.runOnUiThread(new Runnable() {
			@Override
			public void run() {
				mArrayAdapter.clear();
				for(PlayerDevice aPlayerDevice:mArrPlayerDevice) {
					mArrayAdapter.add(aPlayerDevice.namaPlayer + " - " + aPlayerDevice.jumGundu); 
				}				
			}        		
		});   
    }      
    
    @Override
    public void onBackPressed() {	
    	overridePendingTransition(R.anim.fade, R.anim.hold);
    	this.finish();
    }
    
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        case R.id.startGame:            
            GameSettingHolder.PlayingPlayer.clear();
            for(int i=0;i<mArrPlayerDevice.size();i++) {
            	//isi data player yang main dengan player yang ada di room
            	GameSettingHolder.PlayingPlayer.add(new Player(mArrPlayerDevice.get(i).namaPlayer,mArrPlayerDevice.get(i).avatar,i));            	
            }
            GameSettingHolder.numPlayer = GameSettingHolder.PlayingPlayer.size();            
            //jika isi pemain lebih dari dua baru mulai gameview(multiplayer gak bisa sendirian doang mainnya)
            if(GameSettingHolder.PlayingPlayer.size()>1) {
            	if(SelectServerGameActivity.validasi(GameSettingHolder.modegame, GameSettingHolder.taruhan, GameSettingHolder.PlayingPlayer).size()>0) {
            		//jika ternyata ada pesan kesalahan            		
            		for(String message : SelectServerGameActivity.validasi(GameSettingHolder.modegame, GameSettingHolder.taruhan, GameSettingHolder.PlayingPlayer)) {
            			Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
            		}
            		return true;
            	}
            	GameSound.changeMusicFromMainToGame(this);//ganti musik main menu jadi musik game
            	Bundle b = new Bundle();            	
            	Intent gameMultiplayerIntent = new Intent(self, GameActivity.class);
            	b.putBoolean("isMultiplayer", true);
            	gameMultiplayerIntent.putExtras(b);//pas ke gameactivity bahwa player yang digunakan bukan dari hape ini semua            	
            	startActivityForResult(gameMultiplayerIntent, GAME_RESULT_CODE);
            	overridePendingTransition(R.anim.fade, R.anim.hold);
            }else{
            	Toast.makeText(self, "Permainan baru bisa dimulai jika jumlah pemain melebihi satu", Toast.LENGTH_SHORT).show();
            }
            return true;
        }
        return false;
    }
    
    public void updatePlayerOnDevice(String device, String namaPlayer, int gunduMenang, int taruhan, boolean win) {
    	Log.d(TAG,"UPDATE_PLAYER:"+namaPlayer+"::::::::"+gunduMenang+"::::::::"+taruhan+"::::::::"+win);    	
    	if(mConnection.getAddress().equals(device)) {
    		//jika dirinya sendiri
    		Utility.playerHolder.updatePlayerData(this, namaPlayer, gunduMenang, taruhan, win);
    	}else{
    		mConnection.sendMessage(device, "UPDATE_PLAYER:"+namaPlayer+"::::::::"+gunduMenang+"::::::::"+taruhan+"::::::::"+win);
    	}
    }
    
    public PlayerDevice getPlayerDeviceWithPlayerName(String playerName) {
    	for(PlayerDevice aPlayerDevice:mArrPlayerDevice) {
    		if(aPlayerDevice.namaPlayer.equals(playerName)) {
    			return aPlayerDevice;
    		}
    	}
    	return null;
    }        
    
    public void mulaiGame() {
    	GameSettingHolder.PlayingPlayer.clear();
        for(int i=0;i<mArrPlayerDevice.size();i++) {
        	//isi data player yang main dengan player yang ada di room
        	GameSettingHolder.PlayingPlayer.add(new Player(mArrPlayerDevice.get(i).namaPlayer,mArrPlayerDevice.get(i).avatar,i));            	
        }
        GameSettingHolder.numPlayer = GameSettingHolder.PlayingPlayer.size();            
        //jika isi pemain lebih dari dua baru mulai gameview(multiplayer gak bisa sendirian doang mainnya)
        if(GameSettingHolder.PlayingPlayer.size()>1) {
        	if(SelectServerGameActivity.validasi(GameSettingHolder.modegame, GameSettingHolder.taruhan, GameSettingHolder.PlayingPlayer).size()>0) {
        		//jika ternyata ada pesan kesalahan            		
        		for(String message : SelectServerGameActivity.validasi(GameSettingHolder.modegame, GameSettingHolder.taruhan, GameSettingHolder.PlayingPlayer)) {
        			Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
        		}
        		return;
        	}
        	GameSound.changeMusicFromMainToGame(this);//ganti musik main menu jadi musik game
        	Bundle b = new Bundle();            	
        	Intent gameMultiplayerIntent = new Intent(self, GameActivity.class);
        	b.putBoolean("isMultiplayer", true);
        	gameMultiplayerIntent.putExtras(b);//pas ke gameactivity bahwa player yang digunakan bukan dari hape ini semua            	
        	startActivityForResult(gameMultiplayerIntent, GAME_RESULT_CODE);
        	overridePendingTransition(R.anim.fade, R.anim.hold);
        }else{
        	Toast.makeText(self, "Permainan baru bisa dimulai jika jumlah pemain melebihi satu", Toast.LENGTH_SHORT).show();
        }        
    }
}
